//----------------------------------------------------------------------------
// James Mathews
// 3/10/2010
// New prospeckz template 
// Based on code from Steven Wong and Matthew Barnes
//----------------------------------------------------------------------------

//PSoc port defintions
#include "psocapi.h"
#include "psocgpioint.h"
//Prospeckz api
#include "prospeckz.h"
#include "prospeckz_radio.h"

#include "StopAndWait.h"
#include "xlowpan.h"

#include "lcd.h"

#include "MAC.h"
#include "dynmem.h"

#include "discovery.h"

struct xlowpan_addr64 MyAddr;

unsigned char B0_Pressed(void){
	B0_Data_ADDR &= ~B0_MASK;	//force low
	if (B0_Data_ADDR & B0_MASK)
		return TRUE;
	else
		return FALSE;		
}

unsigned char B1_Pressed(void){
	B1_Data_ADDR &= ~B1_MASK;	//force low
	if (B1_Data_ADDR & B1_MASK)
		return TRUE;
	else
		return FALSE;		
}

unsigned char B2_Pressed(void){
	B2_Data_ADDR &= ~B2_MASK;	//force low
	if (B2_Data_ADDR & B2_MASK)
		return TRUE;
	else
		return FALSE;		
}

void BCastHandler(struct xlowpan_addr64* from, void* data, unsigned char hops, unsigned int length)
{
	//only decode a broadcast if we didn't send it.
	if(xlowpan_addrcmp(from, xlowpan_getaddr()))
		discovery_decodepacket(from, data, hops, length);
}

unsigned int send_handler(struct xlowpan_addr64* to, void* data, unsigned int length)
{
	return xlowpan_send(to,data,length);
}

void receive_handler(struct xlowpan_addr64* from, unsigned char* data, unsigned char hops, unsigned int length)
{
	discovery_decodepacket(from, data, hops, length);
}

unsigned char _memory1[256];
unsigned char _memory2[256];
unsigned char _memory3[256];

//#define BASESTATION
#define IP_LSB '2'

void pause(int i)
{
	while(i--)
	{
		unsigned int j = 50000;
		while(j--)MAC_CheckRadio();
	}
}

void main(void)
{
	unsigned char pressed = 0;

	LED_Off;

	dynmem_init(_memory1+1,255);
	dynmem_append(_memory2+1,255);
	dynmem_append(_memory3+1,255);

	discovery_set_cdata("Coolio");

	MyAddr.addr[0] = 't';
	MyAddr.addr[1] = 'e';
	MyAddr.addr[2] = 's';
	MyAddr.addr[3] = 't';
	#ifdef BASESTATION
	MyAddr.addr[4] = 'b';
	#else
	MyAddr.addr[4] = '0';
	#endif
	MyAddr.addr[5] = '0';
	MyAddr.addr[6] = '0';
	MyAddr.addr[7] = IP_LSB;

	Reliable_Init(&MyAddr, 20);
	Reliable_SetSendHandler(send_handler);
	
	MAC_SetBCastHandler(BCastHandler);
	
	M8C_EnableIntMask(INT_MSK0,INT_MSK0_GPIO);	//Enable interupts on the GPIO port
	M8C_EnableGInt;	//Enable intterupts
		
	lcd_setup();
	lcd_clear();
	
	lcd_set_pos(0,0);
	
	#ifndef BASESTATION
	discovery_find_basestation();
	
	pause(10);
	
	discovery_find_basestation_end();
	
	{
		struct xlowpan_addr64* bs = discovery_get_basestation();
		if(bs != NULL)
		{
			char buffer[4];
			int i = 0;
			lcd_set_pos(0,0);
			for(i=0;i<8;i++)
			{
				lcd_print_char(bs->addr[i]);
			}
			LED_Off;
			LED_GREEN_On;
		}
		else
		{
			lcd_set_pos(0,0);
			lcd_print_cstring("!!FAILED!!");
			LED_Off;
			LED_RED_On;
		}
	}
	LED_BLUE_On;
	
	discovery_start();
	pause(10);
	
	lcd_set_pos(1,0);
	{
		struct xlowpan_addr64* addresses;
		int i = 0;
		int count = discovery_end(&addresses);
		char buffer[2];
		utoa(buffer, count, 10);
		lcd_print_string(buffer);
		
		for(i = 0; i < count;i++)
		{
			int j = 0;
			struct xlowpan_addr64 address = addresses[i];
			char* string = discovery_get_data(i);
			lcd_set_pos(i+2,0);
			
			for(j = 0; j < 14; j++)
			{
				lcd_print_char(string[j]);
			}
		}
	}
	LED_BLUE_Off;
	
	while(1)MAC_CheckRadio();
	/* ignore this stuff 
		unsigned char pressed = 0;
		while(1)
		{
			if(B0_Pressed() && !pressed)
			{
				LED_BLUE_On;
				pressed = 1;
				discovery_init();
			}
			if(B1_Pressed() && !pressed)
			{
				LED_GREEN_On;
				discovery_set_cdata("lolol");
				discovery_save();
				pressed = 1;
			}
			if(pressed && !B1_Pressed() && !B2_Pressed())
			{
				LED_Off;
				pressed = 0;
			}
			MAC_CheckRadio();
		}*/
	
	#else
	discovery_set_mode_basestation(1);
	
	while(1) MAC_CheckRadio();
	#endif
}

#pragma interrupt_handler PSoC_GPIO_ISR
void PSoC_GPIO_ISR(void){
	M8C_DisableGInt;
	while(MAC_CheckRadio());
	M8C_EnableGInt;
}